{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PyGw Showcase\n",
    "\n",
    "This notebook demonstrates the some of the utility provided by the `pygw` python package.\n",
    "\n",
    "In this guide, we will show how you can use `pygw` to easily:\n",
    "- **Define** a data schema for Geotools SimpleFeature/Vector data (aka create a new data type)\n",
    "- **Create** instances for the new type\n",
    "- **Create** a RocksDB GeoWave Data Store\n",
    "- **Register** a DataType Adapter & Index to the data store for your new data type\n",
    "- **Write** user-created data into the GeoWave Data Store\n",
    "- **Query** data out of the data store\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "%pip install ../../../../python/src/main/python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Loading state capitals test data set\n",
    "Load state capitals from CSV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import csv\n",
    "\n",
    "with open(\"../../../java-api/src/main/resources/stateCapitals.csv\", encoding=\"utf-8-sig\") as f:\n",
    "    reader = csv.reader(f)\n",
    "    raw_data = [row for row in reader]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Alabama',\n",
       " 'Montgomery',\n",
       " '-86.2460375',\n",
       " '32.343799',\n",
       " '1846',\n",
       " '155.4',\n",
       " '205764',\n",
       " 'scala']"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Let's take a look at what the data looks like\n",
    "raw_data[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the purposes of this exercise, we will use the state name (`[0]`), capital name (`[1]`), longitude (`[2]`), latitude (`[3]`), and the year that the capital was established (`[4]`)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating a new SimpleFeatureType for the state capitals data set\n",
    "\n",
    "We can define a data schema for our data by using a `SimpleFeatureTypeBuilder` to build a `SimpleFeatureType`.\n",
    "\n",
    "We can use the convenience methods defined in `AttributeDescriptor` to define each field of the feature type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pygw.geotools import SimpleFeatureTypeBuilder\n",
    "from pygw.geotools import AttributeDescriptor\n",
    "\n",
    "# Create the feature type builder\n",
    "type_builder = SimpleFeatureTypeBuilder()\n",
    "# Set the name of the feature type\n",
    "type_builder.set_name(\"StateCapitals\")\n",
    "# Add the attributes\n",
    "type_builder.add(AttributeDescriptor.point(\"location\"))\n",
    "type_builder.add(AttributeDescriptor.string(\"state_name\"))\n",
    "type_builder.add(AttributeDescriptor.string(\"capital_name\"))\n",
    "type_builder.add(AttributeDescriptor.date(\"established\"))\n",
    "# Build the feature type\n",
    "state_capitals_type = type_builder.build_feature_type()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating features for each data point using our new SimpleFeatureType\n",
    "\n",
    "`pygw` allows you to create `SimpleFeature` instances for `SimpleFeatureType` using a `SimpleFeatureBuilder`.\n",
    "\n",
    "The `SimpleFeatureBuilder` allows us to specify all of the attributes of a feature, and then build it by providing a feature ID.  For this exercise, we will use the index of the data as the unique feature id.  We will use `shapely` to create the geometries for each feature.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pygw.geotools import SimpleFeatureBuilder\n",
    "from shapely.geometry import Point\n",
    "from datetime import datetime\n",
    "\n",
    "feature_builder = SimpleFeatureBuilder(state_capitals_type)\n",
    "\n",
    "features = []\n",
    "for idx, capital in enumerate(raw_data):\n",
    "    state_name = capital[0]\n",
    "    capital_name = capital[1]\n",
    "    longitude = float(capital[2])\n",
    "    latitude = float(capital[3])\n",
    "    established = datetime(int(capital[4]), 1, 1)\n",
    "    \n",
    "    feature_builder.set_attr(\"location\", Point(longitude, latitude))\n",
    "    feature_builder.set_attr(\"state_name\", state_name)\n",
    "    feature_builder.set_attr(\"capital_name\", capital_name)\n",
    "    feature_builder.set_attr(\"established\", established)\n",
    "    \n",
    "    feature = feature_builder.build(str(idx))\n",
    "    \n",
    "    features.append(feature)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating a data store\n",
    "\n",
    "Now that we have a set of `SimpleFeatures`, let's create a data store to write the features into.  `pygw` supports all of the data store types that GeoWave supports.  All that is needed is to first construct the appropriate `DataStoreOptions` variant that defines the parameters of the data store, then to pass those options to a `DataStoreFactory` to construct the `DataStore`.  In this example we will create a new RocksDB data store."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pygw.store import DataStoreFactory\n",
    "from pygw.store.rocksdb import RocksDBOptions\n",
    "\n",
    "# Specify the options for the data store\n",
    "options = RocksDBOptions()\n",
    "options.set_geowave_namespace(\"geowave.example\")\n",
    "# NOTE: Directory is relative to the JVM working directory.\n",
    "options.set_directory(\"./datastore\")\n",
    "# Create the data store\n",
    "datastore = DataStoreFactory.create_data_store(options)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### An aside: `help()`\n",
    "\n",
    "Much of `pygw` is well-documented, and the `help` method in python can be useful for figuring out what a `pygw` instance can do. Let's try it out on our data store."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on DataStore in module pygw.store.data_store object:\n",
      "\n",
      "class DataStore(pygw.base.geowave_object.GeoWaveObject)\n",
      " |  DataStore(java_ref)\n",
      " |  \n",
      " |  This class models the DataStore interface methods.\n",
      " |  \n",
      " |  Method resolution order:\n",
      " |      DataStore\n",
      " |      pygw.base.geowave_object.GeoWaveObject\n",
      " |      builtins.object\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  __init__(self, java_ref)\n",
      " |      Initialize self.  See help(type(self)) for accurate signature.\n",
      " |  \n",
      " |  add_index(self, type_name, *indices)\n",
      " |      Add new indices for the given type. If there is data in other indices for this type, for\n",
      " |      consistency it will need to copy all of the data into the new indices, which could be a long\n",
      " |      process for lots of data.\n",
      " |      \n",
      " |      Args:\n",
      " |          type_name (str): Name of data type to register indices to.\n",
      " |          *indices (pygw.index.index.Index): Index to add.\n",
      " |  \n",
      " |  add_type(self, type_adapter, *initial_indices)\n",
      " |      Add this type to the data store. This only needs to be called one time per type.\n",
      " |      \n",
      " |      Args:\n",
      " |          type_adapter (pygw.base.data_type_adapter.DataTypeAdapter): The data type adapter to add to the data store.\n",
      " |          *initial_indices (pygw.index.index.Index): The initial indices for this type.\n",
      " |  \n",
      " |  aggregate(self, q)\n",
      " |  \n",
      " |  aggregate_statistics(self, q)\n",
      " |  \n",
      " |  copy_to(self, other, q=None)\n",
      " |      Copy data from this data store to another.\n",
      " |      \n",
      " |      All data is copied if `q` is None, else only the data queried by `q`.\n",
      " |      \n",
      " |      Args:\n",
      " |          other (pygw.store.data_store.DataStore): The data store to copy to.\n",
      " |          q (pygw.query.query.Query): Query filter for data to be copied.\n",
      " |  \n",
      " |  create_writer(self, type_adapter_name)\n",
      " |      Returns an index writer to perform batched write operations for the given data type name.\n",
      " |      \n",
      " |      Assumes the type has already been used previously or added using `add_type` and assumes one or\n",
      " |      more indices have been provided for this type.\n",
      " |      \n",
      " |      Args:\n",
      " |          type_name (str): The name of the type to write to.\n",
      " |      Returns:\n",
      " |          A `pygw.base.writer.Writer`, which can be used to write entries into the data store of the given type.\n",
      " |  \n",
      " |  delete(self, q)\n",
      " |      Delete all data in this data store that matches the query parameter.\n",
      " |      \n",
      " |      Args:\n",
      " |          q (pygw.query.query.Query): The query criteria to use for deletion.\n",
      " |      Returns:\n",
      " |          True on success, False on fail.\n",
      " |  \n",
      " |  delete_all(self)\n",
      " |      Delete ALL data and ALL metadata for this datastore.\n",
      " |      \n",
      " |      Returns:\n",
      " |          True on success, False on fail.\n",
      " |  \n",
      " |  get_indices(self, type_name=None)\n",
      " |      Get the indices that have been registered with this data store for a given type.\n",
      " |      \n",
      " |      Gets all registered indices if `type_name` is None.\n",
      " |      \n",
      " |      Args:\n",
      " |          type_name (str): The name of the type.\n",
      " |      Returns:\n",
      " |          List of `pygw.index.index.Index` in the data store.\n",
      " |  \n",
      " |  get_types(self)\n",
      " |      Get all the data type adapters that have been used within this data store.\n",
      " |      \n",
      " |      Returns:\n",
      " |          List of `pygw.base.data_type_adapter.DataTypeAdapter` used in the data store.\n",
      " |  \n",
      " |  ingest(self, url, *indices, ingest_options=None)\n",
      " |      Ingest from URL.\n",
      " |      \n",
      " |      If this is a directory, this method will recursively search for valid files to\n",
      " |      ingest in the directory. This will iterate through registered IngestFormatPlugins to find one\n",
      " |      that works for a given file.\n",
      " |      \n",
      " |      Args:\n",
      " |          url (str): The URL for data to read and ingest into this data store.\n",
      " |          *indices (pygw.index.index.Index): Index to ingest into.\n",
      " |          ingest_options: Options for ingest (Not yet supported).\n",
      " |  \n",
      " |  query(self, q)\n",
      " |      Returns all data in this data store that matches the query parameter. All data that matches the\n",
      " |      query will be returned as an instance of the native data type. The Iterator must be closed when\n",
      " |      it is no longer needed - this wraps the underlying scanner implementation and closes underlying\n",
      " |      resources.\n",
      " |      \n",
      " |      Args:\n",
      " |          q (pygw.query.query.Query): The query to preform.\n",
      " |      Returns:\n",
      " |          A closeable iterable of results.  The `pygw.base.closeable_iterator.CloseableIterator.close` method should be called\n",
      " |          on the iterator when it is done being used.\n",
      " |  \n",
      " |  query_statistics(self, q)\n",
      " |  \n",
      " |  remove_index(self, index_name, type_name=None)\n",
      " |      Remove an index for a given data type.\n",
      " |      \n",
      " |      If `type_name` is None, the specified index is removed for all types.\n",
      " |      \n",
      " |      Args:\n",
      " |          index_name (str): Name of the index to be removed.\n",
      " |          type_name (str): Name of data type to remove.\n",
      " |      Raises:\n",
      " |          Exception: If the index was the last index of a type.\n",
      " |  \n",
      " |  remove_type(self, type_name)\n",
      " |      Remove all data and statistics associated with the given type.\n",
      " |      \n",
      " |      Args:\n",
      " |          type_name (str): Name of the data type.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from pygw.base.geowave_object.GeoWaveObject:\n",
      " |  \n",
      " |  __eq__(self, other)\n",
      " |      Return self==value.\n",
      " |  \n",
      " |  __repr__(self)\n",
      " |      Return repr(self).\n",
      " |  \n",
      " |  is_instance_of(self, java_class)\n",
      " |      Returns:\n",
      " |          True if this object is of the type represented by the given java class.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors inherited from pygw.base.geowave_object.GeoWaveObject:\n",
      " |  \n",
      " |  __dict__\n",
      " |      dictionary for instance variables (if defined)\n",
      " |  \n",
      " |  __weakref__\n",
      " |      list of weak references to the object (if defined)\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data and other attributes inherited from pygw.base.geowave_object.GeoWaveObject:\n",
      " |  \n",
      " |  __hash__ = None\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(datastore)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adding our data to the data store\n",
    "\n",
    "To store data into our data store, we first have to register a `DataTypeAdapter` for our simple feature data and create an index that defines how the data is queried.  GeoWave supports simple feature data through the use of a `FeatureDataAdapter`.  All that is needed for a `FeatureDataAdapter` is a `SimpleFeatureType`.  We will also add both spatial and spatial/temporal indices."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pygw.geotools import FeatureDataAdapter\n",
    "\n",
    "# Create an adapter for feature type\n",
    "state_capitals_adapter = FeatureDataAdapter(state_capitals_type)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pygw.index import SpatialIndexBuilder\n",
    "from pygw.index import SpatialTemporalIndexBuilder\n",
    "\n",
    "# Add a spatial index\n",
    "spatial_idx = SpatialIndexBuilder().set_name(\"spatial_idx\").create_index()\n",
    "\n",
    "# Add a spatial/temporal index\n",
    "spatial_temporal_idx = SpatialTemporalIndexBuilder().set_name(\"spatial_temporal_idx\").create_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Now we can add our type to the data store with our spatial index\n",
    "datastore.add_type(state_capitals_adapter, spatial_idx, spatial_temporal_idx)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "StateCapitals\n"
     ]
    }
   ],
   "source": [
    "# Check that we've successfully registered an index and type\n",
    "registered_types = datastore.get_types()\n",
    "\n",
    "for t in registered_types:\n",
    "    print(t.get_type_name())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "spatial_idx\n",
      "spatial_temporal_idx\n"
     ]
    }
   ],
   "source": [
    "registered_indices = datastore.get_indices(state_capitals_adapter.get_type_name())\n",
    "\n",
    "for i in registered_indices:\n",
    "    print(i.get_name())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Writing data to our store\n",
    "Now our data store is ready to receive our feature data.  To do this, we must create a `Writer` for our data type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a writer for our data\n",
    "writer = datastore.create_writer(state_capitals_adapter.get_type_name())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Writing data to the data store\n",
    "for ft in features:\n",
    "    writer.write(ft)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Close the writer when we are done with it\n",
    "writer.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Querying our store to make sure the data was ingested properly\n",
    "`pygw` supports querying data in the same fashion as the Java API.  You can use a `VectorQueryBuilder` to create queries on simple feature data sets.  We will use one now to query all of the state capitals in the data store."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pygw.query import VectorQueryBuilder\n",
    "\n",
    "# Create the query builder\n",
    "query_builder = VectorQueryBuilder()\n",
    "\n",
    "# When you don't supply any constraints to the query builder, everything will be queried\n",
    "query = query_builder.build()\n",
    "\n",
    "# Execute the query\n",
    "results = datastore.query(query)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The results returned above is a closeable iterator of `SimpleFeature` objects.  Let's define a function that we can use to print out some information about these feature and then close the iterator when we are finished with it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_results(results):\n",
    "    for result in results:\n",
    "        capital_name = result.get_attribute(\"capital_name\")\n",
    "        state_name = result.get_attribute(\"state_name\")\n",
    "        established = result.get_attribute(\"established\")\n",
    "        print(\"{}, {} was established in {}\".format(capital_name, state_name, established.year))\n",
    "    \n",
    "    # Close the iterator\n",
    "    results.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Honolulu, Hawaii was established in 1845\n",
      "Phoenix, Arizona was established in 1889\n",
      "Baton Rouge, Louisiana was established in 1880\n",
      "Jackson, Mississippi was established in 1821\n",
      "Austin, Texas was established in 1839\n",
      "Topeka, Kansas was established in 1856\n",
      "Oklahoma City, Oklahoma was established in 1910\n",
      "Little Rock, Arkansas was established in 1821\n",
      "Jefferson City, Missouri was established in 1826\n",
      "Des Moines, Iowa was established in 1857\n",
      "Saint Paul, Minnesota was established in 1849\n",
      "Lincoln, Nebraska was established in 1867\n",
      "Pierre, South Dakota was established in 1889\n",
      "Cheyenne, Wyoming was established in 1869\n",
      "Denver, Colorado was established in 1867\n",
      "Santa Fe, New Mexico was established in 1610\n",
      "Salt Lake City, Utah was established in 1858\n",
      "Boise, Idaho was established in 1865\n",
      "Salem, Oregon was established in 1855\n",
      "Carson City, Nevada was established in 1861\n",
      "Sacramento, California was established in 1854\n",
      "Juneau, Alaska was established in 1906\n",
      "Olympia, Washington was established in 1853\n",
      "Helena, Montana was established in 1875\n",
      "Bismarck, North Dakota was established in 1883\n",
      "Augusta, Maine was established in 1832\n",
      "Montpelier, Vermont was established in 1805\n",
      "Boston, Massachusetts was established in 1630\n",
      "Concord, New Hampshire was established in 1808\n",
      "Providence, Rhode Island was established in 1900\n",
      "Hartford, Connecticut was established in 1875\n",
      "Dover, Delaware was established in 1777\n",
      "Raleigh, North Carolina was established in 1792\n",
      "Richmond, Virginia was established in 1780\n",
      "Annapolis, Maryland was established in 1694\n",
      "Harrisburg, Pennsylvania was established in 1812\n",
      "Trenton, New Jersey was established in 1784\n",
      "Albany, New York was established in 1797\n",
      "Columbus, Ohio was established in 1816\n",
      "Lansing, Michigan was established in 1847\n",
      "Madison, Wisconsin was established in 1838\n",
      "Springfield, Illinois was established in 1837\n",
      "Indianapolis, Indiana was established in 1825\n",
      "Frankfort, Kentucky was established in 1792\n",
      "Nashville, Tennessee was established in 1826\n",
      "Atlanta, Georgia was established in 1868\n",
      "Charleston, West Virginia was established in 1885\n",
      "Columbia, South Carolina was established in 1786\n",
      "Tallahassee, Florida was established in 1824\n",
      "Montgomery, Alabama was established in 1846\n"
     ]
    }
   ],
   "source": [
    "# Print the results\n",
    "print_results(results)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Constraining the results\n",
    "Querying all of the data can be useful occasionally, but most of the time we will want to filter the data to only return results that we are interested in.  `pygw` supports several types of constraints to make querying data as flexible as possible."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### CQL Constraints\n",
    "One way you might want to query the data is using a simple CQL query."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A CQL expression for capitals that are in the northeastern part of the US\n",
    "cql_expression = \"BBOX(location, -87.83,36.64,-66.74,48.44)\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create the query builder\n",
    "query_builder = VectorQueryBuilder()\n",
    "query_builder.add_type_name(state_capitals_adapter.get_type_name())\n",
    "\n",
    "# If we want, we can tell the query builder to use the spatial index, since we aren't using time\n",
    "query_builder.index_name(spatial_idx.get_name())\n",
    "\n",
    "# Get the constraints factory\n",
    "constraints_factory = query_builder.constraints_factory()\n",
    "# Create the cql constraints\n",
    "constraints = constraints_factory.cql_constraints(cql_expression)\n",
    "\n",
    "# Set the constraints and build the query\n",
    "query = query_builder.constraints(constraints).build()\n",
    "# Execute the query\n",
    "results = datastore.query(query)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Augusta, Maine was established in 1832\n",
      "Montpelier, Vermont was established in 1805\n",
      "Boston, Massachusetts was established in 1630\n",
      "Concord, New Hampshire was established in 1808\n",
      "Providence, Rhode Island was established in 1900\n",
      "Hartford, Connecticut was established in 1875\n",
      "Dover, Delaware was established in 1777\n",
      "Richmond, Virginia was established in 1780\n",
      "Annapolis, Maryland was established in 1694\n",
      "Harrisburg, Pennsylvania was established in 1812\n",
      "Trenton, New Jersey was established in 1784\n",
      "Albany, New York was established in 1797\n",
      "Columbus, Ohio was established in 1816\n",
      "Lansing, Michigan was established in 1847\n",
      "Indianapolis, Indiana was established in 1825\n",
      "Frankfort, Kentucky was established in 1792\n",
      "Charleston, West Virginia was established in 1885\n"
     ]
    }
   ],
   "source": [
    "# Display the results\n",
    "print_results(results)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Spatial/Temporal Constraints\n",
    "You may also want to contrain the data by both spatial and temporal constraints using the `SpatialTemporalConstraintsBuilder`.  For this example, we will query all capitals that were established after 1800 within 10 degrees of Washington DC."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create the query builder\n",
    "query_builder = VectorQueryBuilder()\n",
    "query_builder.add_type_name(state_capitals_adapter.get_type_name())\n",
    "\n",
    "# We can tell the builder to use the spatial/temporal index\n",
    "query_builder.index_name(spatial_temporal_idx.get_name())\n",
    "\n",
    "# Get the constraints factory\n",
    "constraints_factory = query_builder.constraints_factory()\n",
    "# Create the spatial/temporal constraints builder\n",
    "constraints_builder = constraints_factory.spatial_temporal_constraints()\n",
    "# Create the spatial constraint geometry.\n",
    "washington_dc_buffer = Point(-77.035, 38.894).buffer(10.0)\n",
    "# Set the spatial constraint\n",
    "constraints_builder.spatial_constraints(washington_dc_buffer)\n",
    "# Set the temporal constraint\n",
    "constraints_builder.add_time_range(datetime(1800,1,1), datetime.now())\n",
    "# Build the constraints\n",
    "constraints = constraints_builder.build()\n",
    "\n",
    "# Set the constraints and build the query\n",
    "query = query_builder.constraints(constraints).build()\n",
    "# Execute the query\n",
    "results = datastore.query(query)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Harrisburg, Pennsylvania was established in 1812\n",
      "Columbus, Ohio was established in 1816\n",
      "Indianapolis, Indiana was established in 1825\n",
      "Montpelier, Vermont was established in 1805\n",
      "Concord, New Hampshire was established in 1808\n",
      "Providence, Rhode Island was established in 1900\n",
      "Hartford, Connecticut was established in 1875\n",
      "Charleston, West Virginia was established in 1885\n",
      "Atlanta, Georgia was established in 1868\n",
      "Augusta, Maine was established in 1832\n",
      "Lansing, Michigan was established in 1847\n"
     ]
    }
   ],
   "source": [
    "# Display the results\n",
    "print_results(results)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Filter Factory Constraints\n",
    "We can also use the `FilterFactory` to create more complicated filters.  For example, if we wanted to find all of the capitals within 500 miles of Washington DC that contain the letter L that were established after 1830."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pygw.query import FilterFactory\n",
    "\n",
    "# Create the filter factory\n",
    "filter_factory = FilterFactory()\n",
    "\n",
    "# Create a filter that passes when the capital location is within 500 miles of the\n",
    "# literal location of Washington DC\n",
    "location_prop = filter_factory.property(\"location\")\n",
    "washington_dc_lit = filter_factory.literal(Point(-77.035, 38.894))\n",
    "distance_km = 500 * 1.609344 # Convert miles to kilometers\n",
    "distance_filter = filter_factory.dwithin(location_prop, washington_dc_lit, distance_km, \"kilometers\")\n",
    "\n",
    "# Create a filter that passes when the capital name contains the letter L.\n",
    "capital_name_prop = filter_factory.property(\"capital_name\")\n",
    "name_filter = filter_factory.like(capital_name_prop, \"*l*\")\n",
    "\n",
    "# Create a filter that passes when the established date is after 1830\n",
    "established_prop = filter_factory.property(\"established\")\n",
    "date_lit = filter_factory.literal(datetime(1830, 1, 1))\n",
    "date_filter = filter_factory.after(established_prop, date_lit)\n",
    "\n",
    "# Combine the name, distance, and date filters\n",
    "combined_filter = filter_factory.and_([distance_filter, name_filter, date_filter])\n",
    "\n",
    "# Create the query builder\n",
    "query_builder = VectorQueryBuilder()\n",
    "query_builder.add_type_name(state_capitals_adapter.get_type_name())\n",
    "\n",
    "# Get the constraints factory\n",
    "constraints_factory = query_builder.constraints_factory()\n",
    "# Create the filter constraints\n",
    "constraints = constraints_factory.filter_constraints(combined_filter)\n",
    "\n",
    "# Set the constraints and build the query\n",
    "query = query_builder.constraints(constraints).build()\n",
    "# Execute the query\n",
    "results = datastore.query(query)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Lansing, Michigan was established in 1847\n",
      "Atlanta, Georgia was established in 1868\n",
      "Charleston, West Virginia was established in 1885\n"
     ]
    }
   ],
   "source": [
    "# Display the results\n",
    "print_results(results)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using Pandas with GeoWave query results\n",
    "It's fairly easy to load vector features from GeoWave queries into a Pandas DataFrame.  To do this, make sure pandas is installed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install pandas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we will import pandas and issue a query to the datastore to load into a dataframe."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>location</th>\n",
       "      <th>state_name</th>\n",
       "      <th>capital_name</th>\n",
       "      <th>established</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>10</td>\n",
       "      <td>POINT (-157.7989705 21.3280681)</td>\n",
       "      <td>Hawaii</td>\n",
       "      <td>Honolulu</td>\n",
       "      <td>1845-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>POINT (-112.125051 33.6054149)</td>\n",
       "      <td>Arizona</td>\n",
       "      <td>Phoenix</td>\n",
       "      <td>1889-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>17</td>\n",
       "      <td>POINT (-91.11141859999999 30.441474)</td>\n",
       "      <td>Louisiana</td>\n",
       "      <td>Baton Rouge</td>\n",
       "      <td>1880-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>23</td>\n",
       "      <td>POINT (-90.1888874 32.3103284)</td>\n",
       "      <td>Mississippi</td>\n",
       "      <td>Jackson</td>\n",
       "      <td>1821-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>42</td>\n",
       "      <td>POINT (-97.7534014 30.3077609)</td>\n",
       "      <td>Texas</td>\n",
       "      <td>Austin</td>\n",
       "      <td>1839-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>15</td>\n",
       "      <td>POINT (-95.70803100000001 39.0130545)</td>\n",
       "      <td>Kansas</td>\n",
       "      <td>Topeka</td>\n",
       "      <td>1856-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>35</td>\n",
       "      <td>POINT (-97.4791974 35.4826479)</td>\n",
       "      <td>Oklahoma</td>\n",
       "      <td>Oklahoma City</td>\n",
       "      <td>1910-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>3</td>\n",
       "      <td>POINT (-92.33792750000001 34.7240049)</td>\n",
       "      <td>Arkansas</td>\n",
       "      <td>Little Rock</td>\n",
       "      <td>1821-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>24</td>\n",
       "      <td>POINT (-92.1624049 38.5711659)</td>\n",
       "      <td>Missouri</td>\n",
       "      <td>Jefferson City</td>\n",
       "      <td>1826-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>14</td>\n",
       "      <td>POINT (-93.606516 41.5666699)</td>\n",
       "      <td>Iowa</td>\n",
       "      <td>Des Moines</td>\n",
       "      <td>1857-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>22</td>\n",
       "      <td>POINT (-93.10605339999999 44.9397075)</td>\n",
       "      <td>Minnesota</td>\n",
       "      <td>Saint Paul</td>\n",
       "      <td>1849-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>26</td>\n",
       "      <td>POINT (-96.6907283 40.800609)</td>\n",
       "      <td>Nebraska</td>\n",
       "      <td>Lincoln</td>\n",
       "      <td>1867-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>40</td>\n",
       "      <td>POINT (-100.3205385 44.3708241)</td>\n",
       "      <td>South Dakota</td>\n",
       "      <td>Pierre</td>\n",
       "      <td>1889-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>49</td>\n",
       "      <td>POINT (-104.7674045 41.1475325)</td>\n",
       "      <td>Wyoming</td>\n",
       "      <td>Cheyenne</td>\n",
       "      <td>1869-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>5</td>\n",
       "      <td>POINT (-104.8551114 39.7643389)</td>\n",
       "      <td>Colorado</td>\n",
       "      <td>Denver</td>\n",
       "      <td>1867-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>30</td>\n",
       "      <td>POINT (-105.983036 35.6824934)</td>\n",
       "      <td>New Mexico</td>\n",
       "      <td>Santa Fe</td>\n",
       "      <td>1610-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>43</td>\n",
       "      <td>POINT (-111.920485 40.7766079)</td>\n",
       "      <td>Utah</td>\n",
       "      <td>Salt Lake City</td>\n",
       "      <td>1858-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>11</td>\n",
       "      <td>POINT (-116.2338979 43.6008061)</td>\n",
       "      <td>Idaho</td>\n",
       "      <td>Boise</td>\n",
       "      <td>1865-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>36</td>\n",
       "      <td>POINT (-123.0282074 44.9329915)</td>\n",
       "      <td>Oregon</td>\n",
       "      <td>Salem</td>\n",
       "      <td>1855-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>27</td>\n",
       "      <td>POINT (-119.7526546 39.1678334)</td>\n",
       "      <td>Nevada</td>\n",
       "      <td>Carson City</td>\n",
       "      <td>1861-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>4</td>\n",
       "      <td>POINT (-121.4429125 38.5615405)</td>\n",
       "      <td>California</td>\n",
       "      <td>Sacramento</td>\n",
       "      <td>1854-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>1</td>\n",
       "      <td>POINT (-134.1765792 58.3844634)</td>\n",
       "      <td>Alaska</td>\n",
       "      <td>Juneau</td>\n",
       "      <td>1906-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>46</td>\n",
       "      <td>POINT (-122.8938687 47.0393335)</td>\n",
       "      <td>Washington</td>\n",
       "      <td>Olympia</td>\n",
       "      <td>1853-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>25</td>\n",
       "      <td>POINT (-112.0156939 46.5933579)</td>\n",
       "      <td>Montana</td>\n",
       "      <td>Helena</td>\n",
       "      <td>1875-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>33</td>\n",
       "      <td>POINT (-100.7670546 46.809076)</td>\n",
       "      <td>North Dakota</td>\n",
       "      <td>Bismarck</td>\n",
       "      <td>1883-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>18</td>\n",
       "      <td>POINT (-69.730692 44.3334319)</td>\n",
       "      <td>Maine</td>\n",
       "      <td>Augusta</td>\n",
       "      <td>1832-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>44</td>\n",
       "      <td>POINT (-72.5687199 44.2739708)</td>\n",
       "      <td>Vermont</td>\n",
       "      <td>Montpelier</td>\n",
       "      <td>1805-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>20</td>\n",
       "      <td>POINT (-71.0571571 42.3133735)</td>\n",
       "      <td>Massachusetts</td>\n",
       "      <td>Boston</td>\n",
       "      <td>1630-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>28</td>\n",
       "      <td>POINT (-71.5626055 43.2308015)</td>\n",
       "      <td>New Hampshire</td>\n",
       "      <td>Concord</td>\n",
       "      <td>1808-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>38</td>\n",
       "      <td>POINT (-71.42118050000001 41.8169925)</td>\n",
       "      <td>Rhode Island</td>\n",
       "      <td>Providence</td>\n",
       "      <td>1900-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30</th>\n",
       "      <td>6</td>\n",
       "      <td>POINT (-72.680087 41.7656874)</td>\n",
       "      <td>Connecticut</td>\n",
       "      <td>Hartford</td>\n",
       "      <td>1875-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>31</th>\n",
       "      <td>7</td>\n",
       "      <td>POINT (-75.5134199 39.1564159)</td>\n",
       "      <td>Delaware</td>\n",
       "      <td>Dover</td>\n",
       "      <td>1777-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32</th>\n",
       "      <td>32</td>\n",
       "      <td>POINT (-78.6450559 35.843768)</td>\n",
       "      <td>North Carolina</td>\n",
       "      <td>Raleigh</td>\n",
       "      <td>1792-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>33</th>\n",
       "      <td>45</td>\n",
       "      <td>POINT (-77.49326139999999 37.524661)</td>\n",
       "      <td>Virginia</td>\n",
       "      <td>Richmond</td>\n",
       "      <td>1780-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34</th>\n",
       "      <td>19</td>\n",
       "      <td>POINT (-76.5046945 38.9724689)</td>\n",
       "      <td>Maryland</td>\n",
       "      <td>Annapolis</td>\n",
       "      <td>1694-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>35</th>\n",
       "      <td>37</td>\n",
       "      <td>POINT (-76.8804255 40.2821445)</td>\n",
       "      <td>Pennsylvania</td>\n",
       "      <td>Harrisburg</td>\n",
       "      <td>1812-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36</th>\n",
       "      <td>29</td>\n",
       "      <td>POINT (-74.7741221 40.2162772)</td>\n",
       "      <td>New Jersey</td>\n",
       "      <td>Trenton</td>\n",
       "      <td>1784-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37</th>\n",
       "      <td>31</td>\n",
       "      <td>POINT (-73.8113997 42.6681399)</td>\n",
       "      <td>New York</td>\n",
       "      <td>Albany</td>\n",
       "      <td>1797-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>38</th>\n",
       "      <td>34</td>\n",
       "      <td>POINT (-82.99082900000001 39.9829515)</td>\n",
       "      <td>Ohio</td>\n",
       "      <td>Columbus</td>\n",
       "      <td>1816-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>39</th>\n",
       "      <td>21</td>\n",
       "      <td>POINT (-84.559032 42.7086815)</td>\n",
       "      <td>Michigan</td>\n",
       "      <td>Lansing</td>\n",
       "      <td>1847-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>40</th>\n",
       "      <td>48</td>\n",
       "      <td>POINT (-89.4064204 43.0849935)</td>\n",
       "      <td>Wisconsin</td>\n",
       "      <td>Madison</td>\n",
       "      <td>1838-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>41</th>\n",
       "      <td>12</td>\n",
       "      <td>POINT (-89.6708313 39.7638375)</td>\n",
       "      <td>Illinois</td>\n",
       "      <td>Springfield</td>\n",
       "      <td>1837-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>42</th>\n",
       "      <td>13</td>\n",
       "      <td>POINT (-86.13275 39.7797845)</td>\n",
       "      <td>Indiana</td>\n",
       "      <td>Indianapolis</td>\n",
       "      <td>1825-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>43</th>\n",
       "      <td>16</td>\n",
       "      <td>POINT (-84.8666254 38.1944455)</td>\n",
       "      <td>Kentucky</td>\n",
       "      <td>Frankfort</td>\n",
       "      <td>1792-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>44</th>\n",
       "      <td>41</td>\n",
       "      <td>POINT (-86.7852455 36.1866405)</td>\n",
       "      <td>Tennessee</td>\n",
       "      <td>Nashville</td>\n",
       "      <td>1826-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45</th>\n",
       "      <td>9</td>\n",
       "      <td>POINT (-84.420604 33.7677129)</td>\n",
       "      <td>Georgia</td>\n",
       "      <td>Atlanta</td>\n",
       "      <td>1868-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>46</th>\n",
       "      <td>47</td>\n",
       "      <td>POINT (-81.6405384 38.3560436)</td>\n",
       "      <td>West Virginia</td>\n",
       "      <td>Charleston</td>\n",
       "      <td>1885-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>47</th>\n",
       "      <td>39</td>\n",
       "      <td>POINT (-80.9375649 34.0375089)</td>\n",
       "      <td>South Carolina</td>\n",
       "      <td>Columbia</td>\n",
       "      <td>1786-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>48</th>\n",
       "      <td>8</td>\n",
       "      <td>POINT (-84.25685590000001 30.4671395)</td>\n",
       "      <td>Florida</td>\n",
       "      <td>Tallahassee</td>\n",
       "      <td>1824-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>49</th>\n",
       "      <td>0</td>\n",
       "      <td>POINT (-86.2460375 32.343799)</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>Montgomery</td>\n",
       "      <td>1846-01-01 00:00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    id                               location      state_name    capital_name  \\\n",
       "0   10        POINT (-157.7989705 21.3280681)          Hawaii        Honolulu   \n",
       "1    2         POINT (-112.125051 33.6054149)         Arizona         Phoenix   \n",
       "2   17   POINT (-91.11141859999999 30.441474)       Louisiana     Baton Rouge   \n",
       "3   23         POINT (-90.1888874 32.3103284)     Mississippi         Jackson   \n",
       "4   42         POINT (-97.7534014 30.3077609)           Texas          Austin   \n",
       "5   15  POINT (-95.70803100000001 39.0130545)          Kansas          Topeka   \n",
       "6   35         POINT (-97.4791974 35.4826479)        Oklahoma   Oklahoma City   \n",
       "7    3  POINT (-92.33792750000001 34.7240049)        Arkansas     Little Rock   \n",
       "8   24         POINT (-92.1624049 38.5711659)        Missouri  Jefferson City   \n",
       "9   14          POINT (-93.606516 41.5666699)            Iowa      Des Moines   \n",
       "10  22  POINT (-93.10605339999999 44.9397075)       Minnesota      Saint Paul   \n",
       "11  26          POINT (-96.6907283 40.800609)        Nebraska         Lincoln   \n",
       "12  40        POINT (-100.3205385 44.3708241)    South Dakota          Pierre   \n",
       "13  49        POINT (-104.7674045 41.1475325)         Wyoming        Cheyenne   \n",
       "14   5        POINT (-104.8551114 39.7643389)        Colorado          Denver   \n",
       "15  30         POINT (-105.983036 35.6824934)      New Mexico        Santa Fe   \n",
       "16  43         POINT (-111.920485 40.7766079)            Utah  Salt Lake City   \n",
       "17  11        POINT (-116.2338979 43.6008061)           Idaho           Boise   \n",
       "18  36        POINT (-123.0282074 44.9329915)          Oregon           Salem   \n",
       "19  27        POINT (-119.7526546 39.1678334)          Nevada     Carson City   \n",
       "20   4        POINT (-121.4429125 38.5615405)      California      Sacramento   \n",
       "21   1        POINT (-134.1765792 58.3844634)          Alaska          Juneau   \n",
       "22  46        POINT (-122.8938687 47.0393335)      Washington         Olympia   \n",
       "23  25        POINT (-112.0156939 46.5933579)         Montana          Helena   \n",
       "24  33         POINT (-100.7670546 46.809076)    North Dakota        Bismarck   \n",
       "25  18          POINT (-69.730692 44.3334319)           Maine         Augusta   \n",
       "26  44         POINT (-72.5687199 44.2739708)         Vermont      Montpelier   \n",
       "27  20         POINT (-71.0571571 42.3133735)   Massachusetts          Boston   \n",
       "28  28         POINT (-71.5626055 43.2308015)   New Hampshire         Concord   \n",
       "29  38  POINT (-71.42118050000001 41.8169925)    Rhode Island      Providence   \n",
       "30   6          POINT (-72.680087 41.7656874)     Connecticut        Hartford   \n",
       "31   7         POINT (-75.5134199 39.1564159)        Delaware           Dover   \n",
       "32  32          POINT (-78.6450559 35.843768)  North Carolina         Raleigh   \n",
       "33  45   POINT (-77.49326139999999 37.524661)        Virginia        Richmond   \n",
       "34  19         POINT (-76.5046945 38.9724689)        Maryland       Annapolis   \n",
       "35  37         POINT (-76.8804255 40.2821445)    Pennsylvania      Harrisburg   \n",
       "36  29         POINT (-74.7741221 40.2162772)      New Jersey         Trenton   \n",
       "37  31         POINT (-73.8113997 42.6681399)        New York          Albany   \n",
       "38  34  POINT (-82.99082900000001 39.9829515)            Ohio        Columbus   \n",
       "39  21          POINT (-84.559032 42.7086815)        Michigan         Lansing   \n",
       "40  48         POINT (-89.4064204 43.0849935)       Wisconsin         Madison   \n",
       "41  12         POINT (-89.6708313 39.7638375)        Illinois     Springfield   \n",
       "42  13           POINT (-86.13275 39.7797845)         Indiana    Indianapolis   \n",
       "43  16         POINT (-84.8666254 38.1944455)        Kentucky       Frankfort   \n",
       "44  41         POINT (-86.7852455 36.1866405)       Tennessee       Nashville   \n",
       "45   9          POINT (-84.420604 33.7677129)         Georgia         Atlanta   \n",
       "46  47         POINT (-81.6405384 38.3560436)   West Virginia      Charleston   \n",
       "47  39         POINT (-80.9375649 34.0375089)  South Carolina        Columbia   \n",
       "48   8  POINT (-84.25685590000001 30.4671395)         Florida     Tallahassee   \n",
       "49   0          POINT (-86.2460375 32.343799)         Alabama      Montgomery   \n",
       "\n",
       "            established  \n",
       "0   1845-01-01 00:00:00  \n",
       "1   1889-01-01 00:00:00  \n",
       "2   1880-01-01 00:00:00  \n",
       "3   1821-01-01 00:00:00  \n",
       "4   1839-01-01 00:00:00  \n",
       "5   1856-01-01 00:00:00  \n",
       "6   1910-01-01 00:00:00  \n",
       "7   1821-01-01 00:00:00  \n",
       "8   1826-01-01 00:00:00  \n",
       "9   1857-01-01 00:00:00  \n",
       "10  1849-01-01 00:00:00  \n",
       "11  1867-01-01 00:00:00  \n",
       "12  1889-01-01 00:00:00  \n",
       "13  1869-01-01 00:00:00  \n",
       "14  1867-01-01 00:00:00  \n",
       "15  1610-01-01 00:00:00  \n",
       "16  1858-01-01 00:00:00  \n",
       "17  1865-01-01 00:00:00  \n",
       "18  1855-01-01 00:00:00  \n",
       "19  1861-01-01 00:00:00  \n",
       "20  1854-01-01 00:00:00  \n",
       "21  1906-01-01 00:00:00  \n",
       "22  1853-01-01 00:00:00  \n",
       "23  1875-01-01 00:00:00  \n",
       "24  1883-01-01 00:00:00  \n",
       "25  1832-01-01 00:00:00  \n",
       "26  1805-01-01 00:00:00  \n",
       "27  1630-01-01 00:00:00  \n",
       "28  1808-01-01 00:00:00  \n",
       "29  1900-01-01 00:00:00  \n",
       "30  1875-01-01 00:00:00  \n",
       "31  1777-01-01 00:00:00  \n",
       "32  1792-01-01 00:00:00  \n",
       "33  1780-01-01 00:00:00  \n",
       "34  1694-01-01 00:00:00  \n",
       "35  1812-01-01 00:00:00  \n",
       "36  1784-01-01 00:00:00  \n",
       "37  1797-01-01 00:00:00  \n",
       "38  1816-01-01 00:00:00  \n",
       "39  1847-01-01 00:00:00  \n",
       "40  1838-01-01 00:00:00  \n",
       "41  1837-01-01 00:00:00  \n",
       "42  1825-01-01 00:00:00  \n",
       "43  1792-01-01 00:00:00  \n",
       "44  1826-01-01 00:00:00  \n",
       "45  1868-01-01 00:00:00  \n",
       "46  1885-01-01 00:00:00  \n",
       "47  1786-01-01 00:00:00  \n",
       "48  1824-01-01 00:00:00  \n",
       "49  1846-01-01 00:00:00  "
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pandas import DataFrame\n",
    "\n",
    "# Query everything\n",
    "query = VectorQueryBuilder().build()\n",
    "results = datastore.query(query)\n",
    "\n",
    "# Load the results into a pandas dataframe\n",
    "dataframe = DataFrame.from_records([feature.to_dict() for feature in results])\n",
    "\n",
    "# Display the dataframe\n",
    "dataframe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
